package com.ruoyi.ldzlsc.service.Impl;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.ldzlsc.domain.ScWorkOrder;
import com.ruoyi.ldzlsc.domain.ScWorkOrderTask;
import com.ruoyi.ldzlsc.domain.vo.WorkOrderScheduleInfoVO;
import com.ruoyi.ldzlsc.domain.vo.WorkOrderTaskVO;
import com.ruoyi.ldzlsc.domain.vo.WorkOrderVO;
import com.ruoyi.ldzlsc.mapper.ScWorkOrderMapper;
import com.ruoyi.ldzlsc.mapper.ScWorkOrderTaskMapper;
import com.ruoyi.ldzlsc.service.IScWorkOrderService;
import com.ruoyi.ldzlsc.service.IScWorkOrderTaskService;
import com.ruoyi.system.api.RemoteOperationalService;
import com.ruoyi.system.api.RemoteProcessService;
import com.ruoyi.system.api.RemoteStationService;
import com.ruoyi.system.api.domain.BasicOperationalDto;
import com.ruoyi.system.api.domain.BasicProcessDto;
import com.ruoyi.system.api.domain.BasicStationDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 工单Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-31
 */
@Service
public class ScWorkOrderServiceImpl implements IScWorkOrderService {
    @Autowired
    private ScWorkOrderMapper workOrderMapper;
    
    @Autowired
    private ScWorkOrderTaskMapper workOrderTaskMapper;


    @Autowired
    private RemoteOperationalService remoteOperationalService;

    @Autowired
    private RemoteProcessService remoteProcessService;
    
    @Autowired
    private RemoteStationService remoteStationService;

    /**
     * 查询工单列表
     *
     * @param workOrderVO 工单查询条件
     * @return 工单集合
     */
    @Override
    public List<WorkOrderVO> selectWorkOrderList(WorkOrderVO workOrderVO) {
        return workOrderMapper.selectWorkOrderList(workOrderVO);
    }
    
    /**
     * 根据工单ID查询工单详情
     *
     * @param workOrderId 工单ID
     * @return 工单信息
     */
    @Override
    public WorkOrderScheduleInfoVO selectScWorkOrderById(Long workOrderId) {
        // 1. 查询工单主体，直接使用 DTO
        WorkOrderVO workOrderVO = workOrderMapper.selectWorkOrderById(workOrderId);

        if (workOrderVO == null || workOrderVO.getWorkOrderId() == null) {
            return null;
        }

        WorkOrderScheduleInfoVO resultVO = new WorkOrderScheduleInfoVO();
        resultVO.setWorkOrder(workOrderVO);

        // 2. 查询或生成工序任务列表
        List<WorkOrderTaskVO> taskList = workOrderTaskMapper.selectWorkOrderTasksByWorkOrderId(workOrderId);

        if (taskList == null || taskList.isEmpty()) {
            List<WorkOrderTaskVO> generatedTasks = new ArrayList<>();
            R<List<BasicOperationalDto>> operationalResult = remoteOperationalService.getInfoByProductId(workOrderVO.getProductId(), SecurityConstants.INNER);

            if (R.isSuccess(operationalResult) && operationalResult.getData() != null && !operationalResult.getData().isEmpty()) {
                List<BasicOperationalDto> operationalRoutes = operationalResult.getData();
                List<Long> processIds = operationalRoutes.stream().map(BasicOperationalDto::getProcessId).distinct().collect(Collectors.toList());

                if (!processIds.isEmpty()) {
                    R<List<BasicProcessDto>> processResult = remoteProcessService.getProcessListByIds(processIds, SecurityConstants.INNER);
                    if (R.isSuccess(processResult) && processResult.getData() != null) {
                        Map<Long, String> processIdToNameMap = processResult.getData().stream()
                                .collect(Collectors.toMap(BasicProcessDto::getProcess_id, BasicProcessDto::getProcess_name));

                        for (BasicOperationalDto route : operationalRoutes) {
                            WorkOrderTaskVO newTask = new WorkOrderTaskVO();
                            newTask.setWorkOrderId(workOrderId);
                            newTask.setProcessId(route.getProcessId());
                            newTask.setProcessName(processIdToNameMap.get(route.getProcessId()));
                            newTask.setPlannedQty(workOrderVO.getQtyNum());
                            generatedTasks.add(newTask);
                        }
                        taskList = generatedTasks;
                    }
                }
            }
        }
        resultVO.setTaskList(taskList);

        // 3. 统一获取并设置工序和工位列表
        if (taskList != null && !taskList.isEmpty()) {
            List<Long> processIds = taskList.stream().map(WorkOrderTaskVO::getProcessId).distinct().collect(Collectors.toList());
            if (!processIds.isEmpty()) {
                // 获取工序列表
                R<List<BasicProcessDto>> processResult = remoteProcessService.getProcessListByIds(processIds, SecurityConstants.INNER);
                if (R.isSuccess(processResult) && processResult.getData() != null) {
                    resultVO.setProcessList(processResult.getData());
                } else {
                    resultVO.setProcessList(new ArrayList<>());
                }

                // 获取工位列表
                R<List<BasicStationDto>> stationResult = remoteStationService.getStationListByProcessIds(processIds, SecurityConstants.INNER);
                if (R.isSuccess(stationResult) && stationResult.getData() != null) {
                    resultVO.setStationList(stationResult.getData());
                } else {
                    resultVO.setStationList(new ArrayList<>());
                }
            } else {
                resultVO.setProcessList(new ArrayList<>());
                resultVO.setStationList(new ArrayList<>());
            }
        } else {
            resultVO.setProcessList(new ArrayList<>());
            resultVO.setStationList(new ArrayList<>());
        }
        
        return resultVO;
    }
    
    /**
     * 开始工单
     *
     * @param workOrderId 工单ID
     * @param operName 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int startWorkOrder(Long workOrderId, String operName) {
        ScWorkOrder workOrder = new ScWorkOrder();
        workOrder.setWorkOrderId(workOrderId);
        workOrder.setStatus("2"); // 进行中
        workOrder.setActualStartTime(DateUtils.getNowDate());
        workOrder.setUpdateBy(operName);
        return workOrderMapper.updateWorkOrderStatus(workOrder);
    }
    
    /**
     * 取消工单
     *
     * @param workOrderIds 工单ID集合
     * @param operName 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int cancelWorkOrder(Long[] workOrderIds, String operName) {
        int rows = 0;
        for (Long workOrderId : workOrderIds) {
            ScWorkOrder workOrder = new ScWorkOrder();
            workOrder.setWorkOrderId(workOrderId);
            workOrder.setStatus("5"); // 已取消
            workOrder.setUpdateBy(operName);
            rows += workOrderMapper.updateWorkOrderStatus(workOrder);
        }
        return rows;
    }
    
    /**
     * 结束工单
     *
     * @param workOrderId 工单ID
     * @param operName 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int finishWorkOrder(Long workOrderId, String operName) {
        ScWorkOrder workOrder = new ScWorkOrder();
        workOrder.setWorkOrderId(workOrderId);
        workOrder.setStatus("3"); // 已完成
        workOrder.setActualEndTime(DateUtils.getNowDate());
        workOrder.setUpdateBy(operName);
        return workOrderMapper.updateWorkOrderStatus(workOrder);
    }
    
    /**
     * 撤回工单
     *
     * @param workOrderId 工单ID
     * @param operName 操作人
     * @return 结果
     */
    @Override
    @Transactional
    public int withdrawWorkOrder(Long workOrderId, String operName) {
        ScWorkOrder workOrder = new ScWorkOrder();
        workOrder.setWorkOrderId(workOrderId);
        workOrder.setStatus("1"); // 未开始
        workOrder.setActualStartTime(null);
        workOrder.setActualEndTime(null);
        workOrder.setUpdateBy(operName);
        return workOrderMapper.updateWorkOrderStatus(workOrder);
    }
    

    

} 